/*
 * Toedo
 * Copyright (C) 2009-2010 J. Devauchelle and contributors.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 3 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

package org.toedo.gui.views;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.UUID;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.Separator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.Hyperlink;
import org.eclipse.ui.forms.widgets.Section;
import org.toedo.controllers.DataController;
import org.toedo.controllers.MenuController;
import org.toedo.controllers.events.EventConstants;
import org.toedo.controllers.events.EventController;
import org.toedo.gui.actions.DeleteNoteAction;
import org.toedo.gui.actions.RenameBaseNoteAction;
import org.toedo.gui.dialogs.AttachmentsManagementDialog;
import org.toedo.gui.dialogs.TagsManagementDialog;
import org.toedo.gui.listeners.PartListener2Adapter;
import org.toedo.gui.translations.Messages;
import org.toedo.model.BaseNote;
import org.toedo.model.Note;
import org.toedo.utils.ApplicationUtils;
import org.toedo.utils.DateUtils;
import org.toedo.Activator;

public class NoteView extends BaseNoteViewPart implements PropertyChangeListener {
	
	public static final String ID = "toedo-core.NoteView"; //$NON-NLS-1$
	
	private Note mNote = null;
	
	private Hyperlink mChangeTags;
	
	private Action mManageAttachmentsAction;
	private Action mRenameAction;
	private Action mDeleteAction;
	
	private Image mViewImage;

	public NoteView() {
		super();
		Activator.getDefault();
		mViewImage = Activator.getImageDescriptor("/icons/note-16.png").createImage(); //$NON-NLS-1$
		
		buildActions();
	}
	
	private void buildActions() {
		mManageAttachmentsAction = new Action(Messages.NoteView_ManageAttachments) {
			public void run() {
				new AttachmentsManagementDialog(mParent.getShell(), mNote).open();
			}
		};
		mManageAttachmentsAction.setImageDescriptor(Activator.getImageDescriptor("/icons/attachement-16.png")); //$NON-NLS-1$
		
		mRenameAction = new Action(Messages.NoteView_RenameNote) {
			public void run() {
				new RenameBaseNoteAction(mParent.getShell(), mNote).run();
			}
		};
		mRenameAction.setImageDescriptor(Activator.getImageDescriptor("/icons/rename-16.png")); //$NON-NLS-1$
		
		mDeleteAction = new Action(Messages.NoteView_DeleteNote) {
			public void run() {
				new DeleteNoteAction(mParent.getShell(), mNote).run();
			}
		};
		mDeleteAction.setImageDescriptor(Activator.getImageDescriptor("/icons/delete-16.png")); //$NON-NLS-1$
	}

	@Override
	public void createPartControl(Composite parent) {
		mParent = parent;		
		mNote = DataController.getInstance().getProject().getNoteById(UUID.fromString(this.getViewSite().getSecondaryId()));
		
		if (mNote != null) {
			mNote.setViewOpen(true);
			
			buildFormHeader(mNote, mViewImage);
		
			mFocusListener = new PartListener2Adapter() {				
				@Override
				public void partDeactivated(IWorkbenchPartReference partRef) {
					if (partRef.getPart(false) == NoteView.this) {
						MenuController.getInstance().setSwitchEditActionEnabled(false);
					}
				}
				
				@Override
				public void partActivated(IWorkbenchPartReference partRef) {
					if (partRef.getPart(false) == NoteView.this) {
						MenuController.getInstance().setSwitchEditActionEnabled(true);
					}
				}
			};
			this.getViewSite().getPage().addPartListener(mFocusListener);
			
			mForm.getToolBarManager().add(mManageAttachmentsAction);
			mForm.getToolBarManager().add(mRenameAction);
			mForm.getToolBarManager().add(new Separator());
			mForm.getToolBarManager().add(mDeleteAction);
			mForm.getToolBarManager().update(true);
			
			buildContentSection(mNote);
			
			Section detailsSection = mToolkit.createSection(mForm.getBody(), 
					 Section.TITLE_BAR | Section.TWISTIE | Section.EXPANDED);
			detailsSection.setText(Messages.TaskView_DetailsSectionTitle);
			GridData gd = new GridData(SWT.FILL, SWT.FILL, true, false);
			detailsSection.setLayoutData(gd);
			
			Composite dateComposite = mToolkit.createComposite(detailsSection);
			dateComposite.setLayout(new GridLayout(4, false));
			
			mToolkit.createLabel(dateComposite, Messages.NoteView_CreationDate);
			Label creationDateValueLabel = mToolkit.createLabel(dateComposite, null);
			creationDateValueLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
			creationDateValueLabel.setText(DateUtils.dateTimeToDisplayString(mNote.getCreationDate()));
			
			mChangeTags = mToolkit.createHyperlink(dateComposite, Messages.TaskView_TagsLabel, SWT.NONE);
			mChangeTags.addHyperlinkListener(new HyperlinkAdapter(){
				@Override
				public void linkActivated(HyperlinkEvent e) {
					TagsManagementDialog dialog =  new TagsManagementDialog(mParent.getShell(), mNote);					
					dialog.open();
				}
			});
			mTagsList = mToolkit.createLabel(dateComposite, null);
			mTagsList.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
			
			detailsSection.setClient(dateComposite);
					
			buildAttachmentSection(mNote);
			
			updateDisplay();
			
			EventController.getInstance().addGeneralEventsListener(this);
		}

	}
	
	public void switchEditMode() {
		switchEditMode(mNote);
	}
	
	protected void updateDisplay() {
		super.updateDisplay(mNote);
		mForm.layout(true);
	}

	@Override
	public void propertyChange(PropertyChangeEvent arg0) {
		class RefreshViewer implements Runnable {
			public void run() {
				updateDisplay();
			}
		}
		
		if ((arg0.getPropertyName().equals(EventConstants.EVT_MODIFY_NOTE)) ||
				(arg0.getPropertyName().equals(EventConstants.EVT_RENAME_BASENOTE)) ||
				(arg0.getPropertyName().equals(EventConstants.EVT_BASENOTE_TAG_CHANGE)) ||
				(arg0.getPropertyName().equals(EventConstants.EVT_ADD_ATTACHMENT)) ||
				(arg0.getPropertyName().equals(EventConstants.EVT_REMOVE_ATTACHMENT)) ||
				(arg0.getPropertyName().equals(EventConstants.EVT_MODIFY_ATTACHMENT))) {
			
			if (((BaseNote) arg0.getNewValue()).getId().equals(mNote.getId())) {
				Display.getDefault().asyncExec(new RefreshViewer());
				setDirty(true);
			}
		} else if (arg0.getPropertyName().equals(EventConstants.EVT_DELETE_NOTE)) {
			if (((BaseNote) arg0.getNewValue()).getId().equals(mNote.getId())) {
				ApplicationUtils.closeViewByID(NoteView.ID, this.getViewSite().getSecondaryId());				
			}
		} else if (arg0.getPropertyName().equals(EventConstants.EVT_PROJECT_PROPERTIES_CHANGE)) {
			if ((((String) arg0.getNewValue()).equals(EventConstants.EVT_PROJECT_PROPERTIES_DISPLAY_CSS_CHANGE)) ||
					(((String) arg0.getNewValue()).equals(EventConstants.EVT_PROJECT_PROPERTIES_MARKUP_CHANGE))) {
				Display.getDefault().asyncExec(new RefreshViewer());
			}
		} else if (arg0.getPropertyName().equals(EventConstants.EVT_SAVE)) {
			setDirty(false);
		}
		
	}
	
	public void dispose() {
		EventController.getInstance().removeGeneralEventsListener(this);
		
		mNote.setViewOpen(false);
		
		mViewImage.dispose();
		
		super.dispose();
	}
	
	@Override
	public void setFocus() { }
}
